﻿using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Windows8Accelerator.Core.Xaml.Controls;

namespace Windows8Accelerator.Core.Xaml.Helpers
{
    public class SettingsConfig
    {
        public List<SettingsCommandHelper> Commands { get; set; }
        public IApplicationBar AppBar { get; set; }
    }

    public class SettingsCommandHelper
    {
        public Action Action { get; set; }
        public string Title { get; set; }
    }
    
    public static class SettingsContractHelper
    {
        private static Dictionary<PhoneApplicationPage, SettingsConfig> SettingsConfigs = new Dictionary<PhoneApplicationPage, SettingsConfig>();
        private static List<SettingsCommandHelper> AllPagesCommands = new List<SettingsCommandHelper>();

        private static void UnsubscribeForCommandsRequested(PhoneApplicationPage page)
        {
            if (SettingsConfigs.ContainsKey(page))
            {
                SettingsConfigs.Remove(page);
            }
        }

        private static void page_Unloaded(object sender, RoutedEventArgs e)
        {
            UnsubscribeForCommandsRequested((PhoneApplicationPage)sender);
        }

        static void page_Loaded(object sender, RoutedEventArgs e)
        {
            CommandsRequested(sender as PhoneApplicationPage);
        }

        private static void CommandsRequested(PhoneApplicationPage page)
        {
            if (page is SuperFlyoutPage)
                return;

            SettingsConfig settingsConfig;
            if (SettingsConfigs.TryGetValue(page, out settingsConfig))
            {
                foreach (var command in settingsConfig.Commands)
                {
                    AddCommand(settingsConfig.AppBar, command);
                }
                foreach (var command in AllPagesCommands)
                {
                    AddCommand(settingsConfig.AppBar, command);
                }
            }
        }

        private static void AddCommand(IApplicationBar appBar, SettingsCommandHelper command)
        {
            var commandId = string.Format("SettingsContractHelper:{0}", command.Title);
            var menuExists = false;
            foreach (ApplicationBarMenuItem item in appBar.MenuItems)
            {
                if (item.Text.Equals(command.Title))
                {
                    menuExists = true;
                    break;
                }
            }
            if (!menuExists)
            {
                var menuItem = new ApplicationBarMenuItem(command.Title);
                menuItem.Click += (s, e) => {
                    command.Action();
                };
                appBar.MenuItems.Add(menuItem);
            }
        }

        public static void AddSettingsLink(string title, Uri uri)
        {
            AddSettingsLink(title, null, true, uri);
        }

        public static void AddSettingsLink(string title, PhoneApplicationPage page, bool registerInAllPages, Uri uri)
        {
            AddSettingsCommand(title, page, registerInAllPages, () => {
                var wbt = new WebBrowserTask();
                wbt.Uri = uri;
                wbt.Show();
            });
        }

        public static void AddSettingsCommand(string title, Action action)
        {
            AddSettingsCommand(title, null, true, action);
        }

        public static void AddSettingsCommand(string title, PhoneApplicationPage page, bool registerInAllPages, Action action)
        {
            InitializeSettingsPane(page);

            if (!registerInAllPages)
            {
                SettingsConfigs[page].Commands.Add(new SettingsCommandHelper()
                {
                    Title = title,
                    Action = action,
                });
            }
            else
            {
                AllPagesCommands.Add(new SettingsCommandHelper()
                {
                    Title = title,
                    Action = action,
                });

                if (AppHelper.Frame != null)
                {
                    AppHelper.Frame.Navigated += (sender, e) =>
                    {
                        var page1 = e.Content as PhoneApplicationPage;
                        if (page1 != null)
                        {
                            if (!SettingsConfigs.ContainsKey(page1))
                            {
                                SettingsConfigs[page1] = new SettingsConfig()
                                {
                                    AppBar = GetOrCreateAppBar(page1),
                                    Commands = new List<SettingsCommandHelper>(),
                                };
                                page1.Loaded += page_Loaded;
                                page1.Unloaded += page_Unloaded;
                            }
                        }
                    };
                }
            }
        }

        private static IApplicationBar GetOrCreateAppBar(PhoneApplicationPage page)
        {
            if (page.ApplicationBar == null)
                page.ApplicationBar = new ApplicationBar();
            return page.ApplicationBar;
        }

        public static void RemoveSettingsCommand(string title, PhoneApplicationPage page)
        {
            InitializeSettingsPane(page);

            var command = SettingsConfigs[page].Commands.FirstOrDefault((c) => c.Title.Equals(title));
            if (command != null)
                SettingsConfigs[page].Commands.Remove(command);

            command = AllPagesCommands.FirstOrDefault((c) => c.Title.Equals(title));
            if (command != null)
                AllPagesCommands.Remove(command);
        }

        public static void InitializeSettingsPane(PhoneApplicationPage page)
        {
            if (page != null && !SettingsConfigs.ContainsKey(page))
            {
                SettingsConfigs[page] = new SettingsConfig()
                {
                    AppBar = GetOrCreateAppBar(page),
                    Commands = new List<SettingsCommandHelper>(),
                };
                page.Loaded += page_Loaded;
                page.Unloaded += page_Unloaded;
            }
        }

    }
}
